package com.wallace.downloadserver.interceptor

import com.wallace.downloadserver.myconst.DefineName
import com.wallace.downloadserver.myconst.ResponseMessage
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import org.springframework.web.servlet.HandlerInterceptor
import java.util.concurrent.TimeUnit
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * @Description:
 * 拦截两分钟前的请求
 * 记录执行时间
 * @author Wallace
 * @Date 2022/2/10 16:12
 */
@Component
class TimeStampInterceptor : HandlerInterceptor {

    private val log: Logger = LoggerFactory.getLogger(TimeStampInterceptor::class.java)

    override fun preHandle(httpRequest: HttpServletRequest, httpResponse: HttpServletResponse, handler: Any): Boolean {
        // 获取请求头中的时间戳
        val timeStampString = httpRequest.getHeader(DefineName.TIMESTAMP)
        if (timeStampString == null) {
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, ResponseMessage.Error.HEADER_NO_TIMESTAMP)
            return false
        } else {
            var pass: Boolean
            try {
                val timeStamp = timeStampString.toLong()
                val currentTimeStamp = System.currentTimeMillis()
                val interval = currentTimeStamp.minus(timeStamp)
                pass = if ((0L - TimeUnit.MINUTES.toMillis(2)) < interval && interval < TimeUnit.MINUTES.toMillis(2)) {
                    httpRequest.setAttribute(DefineName.START_TIME, currentTimeStamp)
                    true
                } else {
                    log.debug("interval = ${convertTimeUnit(interval)}")
                    httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, ResponseMessage.Error.HEADER_TIMESTAMP_UNTRUSTED)
                    false
                }
            } catch (numberFormatException: java.lang.NumberFormatException) {
                log.warn("$numberFormatException")
                httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, ResponseMessage.Error.HEADER_TIMESTAMP_INCORRECT)
                pass = false
            }
            return pass
        }
    }

    override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?) {
        val startTimeStamp = request.getAttribute(DefineName.START_TIME) as Long
        val currentTimeStamp = System.currentTimeMillis()
        val interval = currentTimeStamp.minus(startTimeStamp)
        val time = convertTimeUnit(interval)
        val record = "请求[${request.requestURI}]执行时间：$time"
        log.debug(record)
    }

    private fun convertTimeUnit(interval: Long): String {
        return when {
            interval > TimeUnit.DAYS.toMillis(1) -> {
                interval.div(TimeUnit.DAYS.toMillis(1)).toString() + "d"
            }
            interval > TimeUnit.HOURS.toMillis(1) -> {
                interval.div(TimeUnit.HOURS.toMillis(1)).toString() + "h"
            }
            interval > TimeUnit.MINUTES.toMillis(1) -> {
                interval.div(TimeUnit.MINUTES.toMillis(1)).toString() + "m"
            }
            interval > TimeUnit.SECONDS.toMillis(1) -> {
                interval.div(TimeUnit.SECONDS.toMillis(1)).toString() + "s"
            }
            else -> interval.div(TimeUnit.MILLISECONDS.toMillis(1)).toString() + "ms"
        }
    }
}

